package com.xiezc.springboot_dht.util;

import com.xiezc.springboot_dht.model.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Becoding编码的文件的解析类, 和生成类
 */
public class BecodeUtil {

    /**
     * 解析方法
     *
     * @param beContent
     * @return
     */
    public static BeObject prase(final BeContent beContent) {

        byte nextChar = beContent.lookCurrent();
        BeType beType = BeType.getByPre(nextChar);

        if (beType == BeType.number) {
            return getNumberBeObject(beContent);
        }

        if (beType == BeType.string) {
            return getStringBeObject(beContent);
        }

        if (beType == BeType.list) {
            return getListBeObject(beContent);
        }

        if (beType == BeType.map) {
            return getMapBeObject(beContent);
        }
        return null;
    }

    public static BeMap getMapBeObject(BeContent beContent) {
        Map<BeObject,BeObject> map = new HashMap<>();
        byte end = beContent.getCurrent();
        while (end != BeType.map.getSuffix()) {
            BeObject key = prase(beContent);
            if (key == null) {
                break;
            }
            BeObject val = prase(beContent);
            map.put(key, val);
            end = beContent.lookCurrent();
        }
        beContent.getCurrent();
        BeMap beMap = new BeMap(map);
        return beMap;
    }

    public static BeList getListBeObject(BeContent beContent) {
        List list = new ArrayList();
        byte end = beContent.getCurrent();
        while (end != BeType.list.getSuffix()) {
            BeObject prase = prase(beContent);
            if (prase == null) {
                break;
            }
            list.add(prase);
            end = beContent.lookCurrent();
        }
        beContent.getCurrent();
        BeList beList = new BeList(list);
        return beList;
    }

    public static BeString getStringBeObject(BeContent beContent) {
        StringBuilder stringBuilder = new StringBuilder();
        char start = (char)beContent.getCurrent();

        while (Character.isDigit(start)) {
            stringBuilder.append(start);
            start = (char)beContent.getCurrent();
        }
        int len = Integer.valueOf(stringBuilder.toString());
        byte[] chars = beContent.getBytes(len);
        BeString beString = new BeString(chars);
        return beString;
    }

    public static BeLong getNumberBeObject(BeContent beContent) {
        StringBuilder stringBuilder = new StringBuilder();
        beContent.getCurrent();
        char start = (char)beContent.getCurrent();
        while (start != BeType.number.getSuffix()) {
            stringBuilder.append(start);
            start = (char)beContent.getCurrent();
        }

        BeLong beLong = new BeLong(Long.valueOf(stringBuilder.toString()));
        return beLong;
    }

}
